
#include "highscores.h"

/* my save callback */
const char *
score_cb(mxml_node_t *node,
			  int where)
{
	const char *name;

	name = node->value.element.name;

	if (!strcmp(name, "scores"))
	{
			return ("\n");
	}
	else if (!strcmp(name, "score"))
	{
		if (where == MXML_WS_BEFORE_OPEN)
			return ("\t");
		else if (where == MXML_WS_AFTER_OPEN)
			return ("\n");
		if (where == MXML_WS_BEFORE_CLOSE)
			return ("\t");
		else if (where == MXML_WS_AFTER_CLOSE)
			return ("\n");
	}
	
	
	return (NULL);
}

HighScores::HighScores(Settings* settingsPtr)
{
	_scores.clear();
	_levelsCompleted = 0;
	
	_ptrSettings = settingsPtr;
	
	_inProgress = false;
	_customStory = false;
	_levelIndex = 0;
}

HighScores::~HighScores()
{
	for(int i = 0; i < (int)_scores.size(); i++)
	{
		if(_scores[i])
			delete _scores[i];
	}
	
	_scores.clear();
	
}

void HighScores::SetLevelsComplete(int l)
{
	if(l > _levelsCompleted)
		_levelsCompleted = l;
}

bool HighScores::Save()
{

    mxml_node_t *xml;
	mxml_node_t *tree;
	mxml_node_t *node;
	
    char buffer[50];
	
	xml = mxmlNewXML("1.0");
	
	tree = mxmlNewElement(xml, "scores");
	
	for(int i=0; i<(int)_scores.size(); ++i)
	{
		node = mxmlNewElement(tree, "score");
		
		mxmlElementSetAttr(node, "name", _scores[i]->GetLvl());
		
		mxmlElementSetAttr(node, "user", _scores[i]->GetUser());
		
		sprintf(buffer, "%d", _scores[i]->GetTime());
		mxmlElementSetAttr(node, "time", buffer);
		
		sprintf(buffer, "%d", _scores[i]->GetPortal());
		mxmlElementSetAttr(node, "portals", buffer);
	}

	tree = mxmlNewElement(xml, "levelsCompleted");
	sprintf(buffer, "%d", _levelsCompleted);
	mxmlElementSetAttr(tree, "num", buffer);
  
	tree = mxmlNewElement(xml, "SaveGame");
	sprintf(buffer, "%d", (int)_inProgress);
	mxmlElementSetAttr(tree, "inProgress", buffer);
	sprintf(buffer, "%d", (int)_customStory);
	mxmlElementSetAttr(tree, "custom", buffer);
	sprintf(buffer, "%d", _levelIndex);
	mxmlElementSetAttr(tree, "index", buffer);
	
	FILE *fp;

	fp = fopen("/apps/portii/highscores.xml", "w");
			
	if(fp != NULL)
	{
		mxmlSaveFile(xml, fp, score_cb);
	
		fclose(fp);
	
		return true;
	}
	else
	{
		return false;
	}
}
		
bool HighScores::Load()
{
  FILE *fp;
  mxml_node_t *xml;
    
  fp = fopen("/apps/portii/highscores.xml", "r");
  
  if(fp == NULL) return false;
  
  xml = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
  fclose(fp);
  
  mxml_node_t *node;
  mxml_node_t *data;
	
	for(int i = 0; i < (int)_scores.size(); i++)
	{
		if(_scores[i])
			delete _scores[i];
	}

	_scores.clear();
	
  node = mxmlFindElement(xml,xml, "scores", NULL, NULL, MXML_DESCEND); 
  if(node != NULL)
  {
	  //Add cake
	  for(data = mxmlFindElement(node, node, "score", NULL, NULL, MXML_DESCEND); 
			data != NULL; 
			data = mxmlFindElement(data, node, "score", NULL, NULL, MXML_DESCEND))
	  {
			std::string tUser;
			if(mxmlElementGetAttr(data,"user") != NULL)
			{
				tUser = std::string(mxmlElementGetAttr(data,"user"));
			}
			else
			{
				tUser = "???";
			}
			_scores.push_back(new ScoreData((char*)mxmlElementGetAttr(data,"name"), atoi(mxmlElementGetAttr(data,"time")), atoi(mxmlElementGetAttr(data,"portals")), (char*)tUser.c_str()));
	  }
  }
  
  node = mxmlFindElement(xml,xml, "levelsCompleted", NULL, NULL, MXML_DESCEND); 
  if(node != NULL)
  {
	  _levelsCompleted = atoi(mxmlElementGetAttr(node,"num"));
  }
  
  node = mxmlFindElement(xml,xml, "SaveGame", NULL, NULL, MXML_DESCEND); 
  if(node != NULL)
  {
	  _inProgress = (bool)atoi(mxmlElementGetAttr(node,"inProgress"));
	  _customStory = (bool)atoi(mxmlElementGetAttr(node,"custom"));
	  _levelIndex = atoi(mxmlElementGetAttr(node,"index"));
  }
  
  return true;
}
		
bool HighScores::IsHighScore(GameMode::Type mode, char* lvl, int value)
{
	for(int i = 0; i < (int)_scores.size(); i++)
	{
		if(strcmp(_scores[i]->GetLvl(), lvl) == 0)
		{
			switch(mode)
			{
				case GameMode::TIMED:
					if(value < _scores[i]->GetTime())
					{
						_scores[i]->SetTime(value);
						return true;
					}
					else
						return false;
					break;
				case GameMode::PORTAL_COUNT:
					if(value < _scores[i]->GetPortal())
					{
						_scores[i]->SetPortal(value);
						return true;
					}
					else
						return false;
					break;
				default:
					return false;
					break;
			}
		}
	}
	
	//If it made it this far, its not recorded yet, so insert it; and then return true
	switch(mode)
	{
		case GameMode::TIMED:
			_scores.push_back(new ScoreData(lvl, value, UNDEFINED_SCORE, (char*)_ptrSettings->GetUserName()));
			break;
		case GameMode::PORTAL_COUNT:
			_scores.push_back(new ScoreData(lvl, UNDEFINED_SCORE, value, (char*)_ptrSettings->GetUserName()));
			break;
		default:
			return false;
			break;
	}
	
	return false;
}

int HighScores::GetHighScore(GameMode::Type mode, char* lvl)
{
	for(int i = 0; i < (int)_scores.size(); i++)
	{
		if(strcmp(_scores[i]->GetLvl(), lvl) == 0)
		{
			switch(mode)
			{
				case GameMode::TIMED:
					return _scores[i]->GetTime();
					break;
				case GameMode::PORTAL_COUNT:
					return _scores[i]->GetPortal();
				default:
					return UNDEFINED_SCORE;
					break;
			}
		}
	}
	
	return UNDEFINED_SCORE;
}
